package cn.iocoder.yudao.module.reading.service.audio;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.reading.controller.app.audio.vo.AudioPlayReqVO;
import cn.iocoder.yudao.module.reading.controller.app.audio.vo.AudioResourceRespVO;
import cn.iocoder.yudao.module.reading.dal.dataobject.audio.AudioResourceDO;
import cn.iocoder.yudao.module.reading.dal.dataobject.audio.UserAudioRecordDO;
import cn.iocoder.yudao.module.reading.dal.mysql.audio.AudioResourceMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.audio.UserAudioRecordMapper;
import cn.iocoder.yudao.module.reading.service.favorite.FavoriteService;
import cn.iocoder.yudao.module.reading.framework.util.StaticResourceUrlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.reading.enums.ErrorCodeConstants.AUDIO_RESOURCE_NOT_EXISTS;

/**
 * 音频管理 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class AudioServiceImpl implements AudioService {

    @Resource
    private AudioResourceMapper audioResourceMapper;
    @Resource
    private UserAudioRecordMapper userAudioRecordMapper;
    @Resource
    private FavoriteService favoriteService;
    @Resource
    private StaticResourceUrlUtils staticResourceUrlUtils;

    @Override
    public AudioResourceDO getAudioResource(Long id) {
        AudioResourceDO audioResource = audioResourceMapper.selectById(id);
        if (audioResource == null) {
            throw exception(AUDIO_RESOURCE_NOT_EXISTS);
        }
        return audioResource;
    }

    @Override
    public List<AudioResourceRespVO> getAudioResourcesByCategory(Long userId, String category, String language, Integer limit) {
        // 获取音频资源列表
        List<AudioResourceDO> audioResources = audioResourceMapper.selectByCategory(category, language, limit);
        
        if (CollUtil.isEmpty(audioResources)) {
            return new ArrayList<>();
        }
        
        // 获取用户播放记录
        Map<Long, UserAudioRecordDO> playRecords = getUserPlayRecords(userId, audioResources);
        
        // 构建响应
        return buildAudioResourceRespList(userId, audioResources, playRecords);
    }

    @Override
    public List<AudioResourceRespVO> searchAudioResources(Long userId, String keyword, String language) {
        // 搜索音频资源
        List<AudioResourceDO> audioResources = audioResourceMapper.searchAudioResources(keyword, language);
        
        if (CollUtil.isEmpty(audioResources)) {
            return new ArrayList<>();
        }
        
        // 获取用户播放记录
        Map<Long, UserAudioRecordDO> playRecords = getUserPlayRecords(userId, audioResources);
        
        // 构建响应
        return buildAudioResourceRespList(userId, audioResources, playRecords);
    }

    @Override
    public List<AudioResourceRespVO> getRecommendedAudioResources(Long userId, String language, Integer limit) {
        // 获取推荐音频资源
        List<AudioResourceDO> audioResources = audioResourceMapper.selectRecommended(language, limit);
        
        if (CollUtil.isEmpty(audioResources)) {
            return new ArrayList<>();
        }
        
        // 获取用户播放记录
        Map<Long, UserAudioRecordDO> playRecords = getUserPlayRecords(userId, audioResources);
        
        // 构建响应
        return buildAudioResourceRespList(userId, audioResources, playRecords);
    }

    @Override
    public Long saveAudioPlayRecord(Long userId, AudioPlayReqVO playReqVO) {
        // 验证音频资源是否存在
        getAudioResource(playReqVO.getAudioId());
        
        // 查询是否已存在播放记录
        UserAudioRecordDO existingRecord = userAudioRecordMapper.selectByUserIdAndAudioId(userId, playReqVO.getAudioId());
        
        LocalDateTime now = LocalDateTime.now();
        
        if (existingRecord == null) {
            // 创建新记录
            UserAudioRecordDO record = UserAudioRecordDO.builder()
                    .userId(userId)
                    .audioId(playReqVO.getAudioId())
                    .playProgress(playReqVO.getPlayProgress())
                    .playDuration(playReqVO.getPlayDuration())
                    .isCompleted(playReqVO.getIsCompleted())
                    .lastPlayAt(now)
                    .playCount(1)
                    .build();
            
            userAudioRecordMapper.insert(record);
            return record.getId();
        } else {
            // 更新现有记录
            UserAudioRecordDO updateObj = UserAudioRecordDO.builder()
                    .id(existingRecord.getId())
                    .playProgress(playReqVO.getPlayProgress())
                    .playDuration(existingRecord.getPlayDuration() + playReqVO.getPlayDuration())
                    .isCompleted(playReqVO.getIsCompleted())
                    .lastPlayAt(now)
                    .playCount(existingRecord.getPlayCount() + 1)
                    .build();
            
            userAudioRecordMapper.updateById(updateObj);
            return existingRecord.getId();
        }
    }

    @Override
    public List<AudioResourceRespVO> getRecentPlayAudios(Long userId, Integer limit) {
        // 获取最近播放记录
        List<UserAudioRecordDO> recentRecords = userAudioRecordMapper.selectRecentByUserId(userId, limit);

        if (CollUtil.isEmpty(recentRecords)) {
            return new ArrayList<>();
        }

        // 获取音频资源信息
        List<Long> audioIds = recentRecords.stream().map(UserAudioRecordDO::getAudioId).collect(Collectors.toList());
        List<AudioResourceDO> audioResources = audioResourceMapper.selectBatchIds(audioIds);

        // 过滤掉被禁用的音频资源
        Map<Long, AudioResourceDO> audioMap = audioResources.stream()
                .filter(audio -> audio.getEnabled() != null && audio.getEnabled()) // 只保留启用的音频
                .collect(Collectors.toMap(AudioResourceDO::getId, audio -> audio));

        // 构建响应
        // 获取收藏状态
        final Map<Long, Boolean> favoriteStatusMap;
        if (userId != null && CollUtil.isNotEmpty(audioIds)) {
            favoriteStatusMap = favoriteService.batchCheckFavoriteStatus(userId, "audio", audioIds);
        } else {
            favoriteStatusMap = Map.of();
        }

        return recentRecords.stream().map(record -> {
            AudioResourceDO audio = audioMap.get(record.getAudioId());
            if (audio == null) return null; // 音频不存在或已被禁用

            Boolean isFavorited = favoriteStatusMap.getOrDefault(record.getAudioId(), false);
            return buildAudioResourceResp(audio, record, isFavorited);
        }).filter(resp -> resp != null).collect(Collectors.toList());
    }

    @Override
    public void clearPlayRecords(Long userId, String category) {
        if (category == null) {
            // 清空所有播放记录
            userAudioRecordMapper.deleteByUserId(userId);
        } else {
            // 根据分类清空播放记录（需要先查询该分类的音频ID）
            List<AudioResourceDO> categoryAudios = audioResourceMapper.selectByCategory(category, null, null);
            if (CollUtil.isNotEmpty(categoryAudios)) {
                List<Long> audioIds = categoryAudios.stream().map(AudioResourceDO::getId).collect(Collectors.toList());
                List<UserAudioRecordDO> records = userAudioRecordMapper.selectByUserIdAndAudioIds(userId, audioIds);
                if (CollUtil.isNotEmpty(records)) {
                    List<Long> recordIds = records.stream().map(UserAudioRecordDO::getId).collect(Collectors.toList());
                    userAudioRecordMapper.deleteBatchIds(recordIds);
                }
            }
        }
    }

    @Override
    public void deletePlayRecord(Long userId, Long audioId) {
        // 删除指定用户的指定音频播放记录
        userAudioRecordMapper.deleteByUserIdAndAudioId(userId, audioId);
    }

    @Override
    public List<AudioResourceRespVO> getAudiosByBookId(Long userId, Long bookId) {
        // 获取绘本相关音频
        List<AudioResourceDO> audioResources = audioResourceMapper.selectByBookId(bookId);
        
        if (CollUtil.isEmpty(audioResources)) {
            return new ArrayList<>();
        }
        
        // 获取用户播放记录
        Map<Long, UserAudioRecordDO> playRecords = getUserPlayRecords(userId, audioResources);
        
        // 构建响应
        return buildAudioResourceRespList(userId, audioResources, playRecords);
    }

    @Override
    public List<AudioResourceRespVO> getAudiosByBookSetId(Long userId, Long bookSetId) {
        // 获取绘本集相关音频
        List<AudioResourceDO> audioResources = audioResourceMapper.selectByBookSetId(bookSetId);
        
        if (CollUtil.isEmpty(audioResources)) {
            return new ArrayList<>();
        }
        
        // 获取用户播放记录
        Map<Long, UserAudioRecordDO> playRecords = getUserPlayRecords(userId, audioResources);
        
        // 构建响应
        return buildAudioResourceRespList(userId, audioResources, playRecords);
    }

    /**
     * 获取用户播放记录Map
     */
    private Map<Long, UserAudioRecordDO> getUserPlayRecords(Long userId, List<AudioResourceDO> audioResources) {
        if (userId == null || CollUtil.isEmpty(audioResources)) {
            return Map.of();
        }
        
        List<Long> audioIds = audioResources.stream().map(AudioResourceDO::getId).collect(Collectors.toList());
        List<UserAudioRecordDO> records = userAudioRecordMapper.selectByUserIdAndAudioIds(userId, audioIds);
        
        return records.stream().collect(Collectors.toMap(UserAudioRecordDO::getAudioId, record -> record));
    }

    /**
     * 构建音频资源响应列表
     */
    private List<AudioResourceRespVO> buildAudioResourceRespList(Long userId, List<AudioResourceDO> audioResources,
                                                                Map<Long, UserAudioRecordDO> playRecords) {
        // 获取收藏状态
        List<Long> audioIds = audioResources.stream().map(AudioResourceDO::getId).collect(Collectors.toList());
        final Map<Long, Boolean> favoriteStatusMap;
        if (userId != null && CollUtil.isNotEmpty(audioIds)) {
            favoriteStatusMap = favoriteService.batchCheckFavoriteStatus(userId, "audio", audioIds);
        } else {
            favoriteStatusMap = Map.of();
        }

        return audioResources.stream().map(audio -> {
            UserAudioRecordDO record = playRecords.get(audio.getId());
            Boolean isFavorited = favoriteStatusMap.getOrDefault(audio.getId(), false);
            return buildAudioResourceResp(audio, record, isFavorited);
        }).collect(Collectors.toList());
    }

    /**
     * 构建音频资源响应对象
     */
    private AudioResourceRespVO buildAudioResourceResp(AudioResourceDO audio, UserAudioRecordDO record, Boolean isFavorited) {
        AudioResourceRespVO respVO = new AudioResourceRespVO();
        respVO.setId(audio.getId());
        respVO.setTitle(audio.getTitle());

        // 将相对路径转换为完整URL
        respVO.setAudioUrl(staticResourceUrlUtils.toFullUrl(audio.getAudioUrl()));
        respVO.setCover(staticResourceUrlUtils.toFullUrl(audio.getCover()));

        respVO.setDuration(audio.getDuration());
        respVO.setCategory(audio.getCategory());
        respVO.setLanguage(audio.getLanguage());
        respVO.setBookId(audio.getBookId());
        respVO.setBookSetId(audio.getBookSetId());

        // 设置新增字段
        respVO.setSubtitle(audio.getSubtitle() != null ? audio.getSubtitle() : generateSubtitle(audio)); // 使用数据库字段或生成副标题
        respVO.setDurationText(formatDuration(audio.getDuration())); // 格式化时长
        respVO.setSortOrder(audio.getSortOrder());
        respVO.setEnabled(audio.getEnabled());
        respVO.setIsFavorited(isFavorited != null ? isFavorited : false);

        // 设置播放相关字段
        if (record != null) {
            respVO.setPlayCount(record.getPlayCount());
        } else {
            respVO.setPlayCount(0);
        }

        // 设置默认值
        respVO.setLikeCount(0); // 暂时设为0，后续可以扩展点赞功能
        respVO.setIsLiked(false); // 暂时设为false，后续可以扩展点赞功能

        // 设置播放状态
        AudioResourceRespVO.PlayStatusVO playStatus = new AudioResourceRespVO.PlayStatusVO();
        if (record != null) {
            playStatus.setPlayProgress(record.getPlayProgress());
            playStatus.setIsCompleted(record.getIsCompleted());
            playStatus.setPlayCount(record.getPlayCount());
            playStatus.setLastPlayAt(record.getLastPlayAt() != null ? record.getLastPlayAt().toString() : null);
        } else {
            playStatus.setPlayProgress(0);
            playStatus.setIsCompleted(false);
            playStatus.setPlayCount(0);
            playStatus.setLastPlayAt(null);
        }
        respVO.setPlayStatus(playStatus);

        return respVO;
    }

    /**
     * 生成音频副标题
     */
    private String generateSubtitle(AudioResourceDO audio) {
        // 根据语言和分类生成副标题
        StringBuilder subtitle = new StringBuilder();

        if ("english".equals(audio.getLanguage()) || "en".equals(audio.getLanguage())) {
            subtitle.append("英文音频");
        } else if ("chinese".equals(audio.getLanguage()) || "zh".equals(audio.getLanguage())) {
            subtitle.append("中文音频");
        } else {
            subtitle.append("音频内容");
        }

        if (audio.getBookId() != null) {
            subtitle.append(" · 绘本配音");
        } else if (audio.getBookSetId() != null) {
            subtitle.append(" · 绘本集配音");
        }

        return subtitle.toString();
    }

    /**
     * 格式化音频时长
     */
    private String formatDuration(Integer seconds) {
        if (seconds == null || seconds <= 0) {
            return "00:00";
        }

        int minutes = seconds / 60;
        int remainingSeconds = seconds % 60;

        return String.format("%02d:%02d", minutes, remainingSeconds);
    }

    @Override
    public Long getNextAudioResourceId() {
        // 获取当前最大ID
        Long maxId = audioResourceMapper.selectMaxId();
        // 计算下一个ID（如果表为空，从1开始）
        Long nextId = (maxId == null ? 0 : maxId) + 1;

        log.info("获取下一个音频资源ID: {}", nextId);
        return nextId;
    }

}
